home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / mail / Mutt089src.lha / Mutt-0.89i-AMIGA / src / sort.c < prev    next >
C/C++ Source or Header  |  1998-01-28  |  5KB  |  197 lines

  1. /*
  2.  * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
  3.  * 
  4.  *     This program is free software; you can redistribute it and/or modify
  5.  *     it under the terms of the GNU General Public License as published by
  6.  *     the Free Software Foundation; either version 2 of the License, or
  7.  *     (at your option) any later version.
  8.  * 
  9.  *     This program is distributed in the hope that it will be useful,
  10.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *     GNU General Public License for more details.
  13.  * 
  14.  *     You should have received a copy of the GNU General Public License
  15.  *     along with this program; if not, write to the Free Software
  16.  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */ 
  18.  
  19. #include "mutt.h"
  20. #include "sort.h"
  21.  
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <unistd.h>
  26.  
  27. #define SORTCODE(x) (Sort & SORT_REVERSE) ? -(x) : x
  28.  
  29. int compare_size (const void *a, const void *b)
  30. {
  31.   HEADER **pa = (HEADER **) a;
  32.   HEADER **pb = (HEADER **) b;
  33.  
  34.   return (SORTCODE ((*pa)->content->length - (*pb)->content->length));
  35. }
  36.  
  37. int compare_date_sent (const void *a, const void *b)
  38. {
  39.   HEADER **pa = (HEADER **) a;
  40.   HEADER **pb = (HEADER **) b;
  41.  
  42.   return (SORTCODE ((*pa)->date_sent - (*pb)->date_sent));
  43. }
  44.  
  45. int compare_subject (const void *a, const void *b)
  46. {
  47.   HEADER **pa = (HEADER **) a;
  48.   HEADER **pb = (HEADER **) b;
  49.   int rc;
  50.  
  51.   if (!(*pa)->env->real_subj)
  52.   {
  53.     if (!(*pb)->env->real_subj)
  54.       rc = compare_date_sent (pa, pb);
  55.     else
  56.       rc = -1;
  57.   }
  58.   else if (!(*pb)->env->real_subj)
  59.     rc = 1;
  60.   else
  61.     rc = strcasecmp ((*pa)->env->real_subj, (*pb)->env->real_subj);
  62.   return (SORTCODE (rc));
  63. }
  64.  
  65. int compare_from (const void *a, const void *b)
  66. {
  67.   HEADER **ppa = (HEADER **) a;
  68.   HEADER **ppb = (HEADER **) b;
  69.   HEADER *pa = *ppa, *pb = *ppb;
  70.   ADDRESS *adr;
  71.   char bufa[SHORT_STRING], bufb[SHORT_STRING];
  72.   char *fa, *fb;
  73.  
  74.   if (option (OPTREVALIAS) && (adr = alias_reverse_lookup (pa->env->from))
  75.                 && adr->personal)
  76.     fa = adr->personal;
  77.   else if (pa->env->from && pa->env->from->personal)
  78.     fa = pa->env->from->personal;
  79.   else
  80.   {
  81.     bufa[0] = 0;
  82.     rfc822_write_address (bufa, sizeof (bufa), pa->env->from);
  83.     fa = bufa;
  84.   }
  85.  
  86.   if (option (OPTREVALIAS) && (adr = alias_reverse_lookup (pb->env->from))
  87.                 && adr->personal)
  88.     fb = adr->personal;
  89.   else if (pb->env->from && pb->env->from->personal)
  90.     fb = pb->env->from->personal;
  91.   else
  92.   {
  93.     bufb[0] = 0;
  94.     rfc822_write_address (bufb, sizeof (bufb), pb->env->from);
  95.     fb = bufb;
  96.   }
  97.  
  98.   return (SORTCODE (strcasecmp (fa, fb)));
  99. }
  100.  
  101. int compare_date_received (const void *a, const void *b)
  102. {
  103.   HEADER **pa = (HEADER **) a;
  104.   HEADER **pb = (HEADER **) b;
  105.   
  106.   return (SORTCODE ((*pa)->received - (*pb)->received));
  107. }
  108.  
  109. int compare_order (const void *a, const void *b)
  110. {
  111.   HEADER **ha = (HEADER **) a;
  112.   HEADER **hb = (HEADER **) b;
  113.  
  114.   return (SORTCODE ((*ha)->index - (*hb)->index));
  115. }
  116.  
  117. sort_t *mutt_get_sort_func (int method)
  118. {
  119.   switch (method & SORT_MASK)
  120.   {
  121.     case SORT_RECEIVED:
  122.       return (compare_date_received);
  123.     case SORT_ORDER:
  124.       return (compare_order);
  125.     case SORT_DATE:
  126.       return (compare_date_sent);
  127.     case SORT_SUBJECT:
  128.       return (compare_subject);
  129.     case SORT_FROM:
  130.       return (compare_from);
  131.     case SORT_SIZE:
  132.       return (compare_size);
  133.     default:
  134.       return (NULL);
  135.   }
  136.   /* not reached */
  137. }
  138.  
  139. void mutt_sort_headers (CONTEXT *ctx, int init)
  140. {
  141.   int i;
  142.   sort_t *sortfunc;
  143.   
  144.   if (!ctx)
  145.     return;
  146.  
  147.   if (!ctx->msgcount)
  148.   {
  149.     /* this function gets called by mutt_sync_mailbox(), which may have just
  150.      * deleted all the messages.  the virtual message numbers are not updated
  151.      * in that routine, so we must make sure to zero the vcount member.
  152.      */
  153.     ctx->vcount = 0;
  154.     ctx->tree = 0;
  155.     return; /* nothing to do! */
  156.   }
  157.  
  158.   if (!ctx->quiet)
  159.     mutt_message ("Sorting mailbox...");
  160.  
  161.   /* threads may be bogus, so clear the links */
  162.   if (init)
  163.     mutt_clear_threads (ctx);
  164.  
  165.   if ((Sort & SORT_MASK) == SORT_THREADS)
  166.     mutt_sort_threads (ctx, init);
  167.   else if ((sortfunc = mutt_get_sort_func (Sort)) == NULL)
  168.   {
  169.     mutt_error ("Could not find sorting function! [report this bug]");
  170.     sleep (1);
  171.     return;
  172.   }
  173.   else 
  174.     qsort ((void *) ctx->hdrs, ctx->msgcount, sizeof (HEADER *), sortfunc);
  175.  
  176.   /* the threading function find_reference() needs to know how the mailbox
  177.    * is currently sorted in memory in order to speed things up a bit
  178.    */
  179.   ctx->revsort = (Sort & SORT_REVERSE) ? 1 : 0;
  180.  
  181.   /* adjust the virtual message numbers */
  182.   ctx->vcount = 0;
  183.   for (i = 0; i < ctx->msgcount; i++)
  184.   {
  185.     if (ctx->hdrs[i]->virtual != -1)
  186.     {
  187.       ctx->hdrs[i]->virtual = ctx->vcount;
  188.       ctx->v2r[ctx->vcount] = i;
  189.       ctx->vcount++;
  190.     }
  191.     ctx->hdrs[i]->msgno = i;
  192.   }
  193.  
  194.   if (!ctx->quiet)
  195.     mutt_clear_error ();
  196. }
  197.